import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:flutter_2b_client/Root.dart';
import 'package:flutter_2b_client/apis/MarketOrderApi.dart';
import 'package:flutter_2b_client/apis/NotificationApi.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:freezed_annotation/freezed_annotation.dart';
import 'package:go_router/go_router.dart';

part 'NotificationManager.g.dart';

part 'NotificationManager.freezed.dart';

const AndroidNotificationChannel marketOrderStatusNotificationChannel =
    AndroidNotificationChannel(
  'marketOrderStatus', // id
  '卖场订单状态变更', // title
  description: '将在你的相关订单被提交时通知', // description
  importance: Importance.max, // importance must be at low or higher level
  playSound: true,
);

typedef NotificationActionHandler = bool Function(
    BuildContext context, NotificationResponse details);

class NotificationManager {
  static final NotificationManager _instance = NotificationManager._internal();

  factory NotificationManager() => _instance;

  NotificationManager._internal();

  final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin =
      FlutterLocalNotificationsPlugin();


  var _next = 0;

  initialize({String androidIcon = '@mipmap/ic_launcher'}) async {
    await _flutterLocalNotificationsPlugin.initialize(
      InitializationSettings(
        iOS: DarwinInitializationSettings(
          onDidReceiveLocalNotification: (id, title, body, payload) {},
        ),
        android: AndroidInitializationSettings(androidIcon),
      ),
      // onDidReceiveBackgroundNotificationResponse: notificationTapBackground,
      onDidReceiveNotificationResponse: (details) {
        var currentContext = rootGoRouterKey.currentContext;
        if (currentContext?.mounted == true) {
          var payloadString = details.payload;
          if(payloadString!=null){
            var notificationPayload = NotificationPayload.fromJson(jsonDecode(payloadString));
            switch(notificationPayload.type){
              case NotificationType.SUBMITTED_MARKET_ORDER:
                var marketOrderDetail = MarketOrderDetail.fromJson(jsonDecode(notificationPayload.data!));
                currentContext!.go("/markets/${marketOrderDetail.market.id}/orders/${marketOrderDetail.id}");
            }
          }
        }
      },
    );

    await _flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.requestNotificationsPermission();

    await _flutterLocalNotificationsPlugin
        .resolvePlatformSpecificImplementation<
            AndroidFlutterLocalNotificationsPlugin>()
        ?.createNotificationChannel(marketOrderStatusNotificationChannel);
  }

  notify(UnconsumedNotification unconsumedNotification) async {
    switch (unconsumedNotification.type) {
      case NotificationType.SUBMITTED_MARKET_ORDER:
        var marketOrderDetail = await marketOrderApi.getMarketOrderDetail(
            (unconsumedNotification.data as Map<String, dynamic>)["id"]);
        var id = await _show(
          title: "新的订单",
          body: "来自${marketOrderDetail.market.name}",
          androidNotificationDetails: AndroidNotificationDetails(
              marketOrderStatusNotificationChannel.id,
              marketOrderStatusNotificationChannel.name,
              channelDescription:
                  marketOrderStatusNotificationChannel.description,
              importance: marketOrderStatusNotificationChannel.importance,
              priority: Priority.min),
          darwinNotificationDetails: const DarwinNotificationDetails(),
          payload: NotificationPayload(
            type: unconsumedNotification.type,
            data: jsonEncode(marketOrderDetail.toJson()),
          ),
        );
        return id;
    }
  }

  Future<int> _show({
    required String title,
    required String body,
    required AndroidNotificationDetails androidNotificationDetails,
    required DarwinNotificationDetails darwinNotificationDetails,
    required NotificationPayload payload,
  }) async {
    var id = _nextId();
    await _flutterLocalNotificationsPlugin.show(
        id,
        title,
        body,
        NotificationDetails(
          android: androidNotificationDetails,
          iOS: darwinNotificationDetails,
        ),
        payload: jsonEncode(payload));
    return id;
  }

  cancel(int id) {
    _flutterLocalNotificationsPlugin.cancel(id);
  }

  int _nextId() {
    return ++_next;
  }
}


@freezed
class NotificationPayload with _$NotificationPayload {
  const factory NotificationPayload(
      {required NotificationType type, String? data}) = _NotificationPayload;

  const NotificationPayload._();

  factory NotificationPayload.fromJson(Map<String, dynamic> json) =>
      _$NotificationPayloadFromJson(json);
}
